/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	EntityChangeLogger.java
 * 模块说明：	
 * 修改历史：
 * 2006-5-16 - lxm, zhangyanbo - 创建。
 */
package com.hd123.rumba.log;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;

import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.runtime.FormatSettings;
import com.hd123.rumba.runtime.IManager;
import com.hd123.rumba.runtime.NamingMgr;

/**
 * 实体属性修改日志 | 生成器 | 实现类
 * 
 * @author lxm
 * @authro zhangyanbo
 * 
 */
public class EntityChangeLogger extends EntityLogger {

  private static final String EVENT_CHANGEFIELD = "修改属性";

  private Integer state = null;

  private IEntityChangeLogMgr logMgr = null;

  public Integer getState() {
    return state;
  }

  public void setState(Integer state) {
    this.state = state;
  }

  public EntityChangeLogger(IManager manager) {
    super(manager);
    try {
      logMgr = (IEntityChangeLogMgr) NamingMgr.getInstance().lookupMgr(IEntityChangeLogMgr.class);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 写实体修改日志。
   * 
   * 参数： fieldName 属性名称。 oldValue 属性修改前的值。 newValue 属性修改后的值。 message 消息。
   * 返回值：IEntityChangeLog
   * 
   * @param fieldName
   *          属性名称。
   * @param oldValue
   *          属性修改前的值。
   * @param newValue
   *          属性修改后的值。
   * @param message
   *          消息。
   * @return
   */
  public IEntityChangeLog changeLog(String fieldName, Object oldValue, Object newValue,
      String message) throws BusinessException {
    if (this.getOperator() == null)
      throw new BusinessException(this.getClass() + ":属性operator不可为空。");
    try {
      IEntityChangeLog ecg = (IEntityChangeLog) logMgr.createLog();
      if (this.getOperator().getDomain() == null) {
        IDomainMgr domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
        ecg.setDomain(domainMgr.getRootDomain());
      } else
        ecg.setDomain(this.getOperator().getDomain());
      ecg.setOperator(this.getOperator().getCodeName());
      ecg.setTime(this.getTime());
      ecg.setEvent(EVENT_CHANGEFIELD);
      ecg.setMessage(message);
      ecg.setManagerClass(this.getManager().getClass().getName());
      ecg.setManagerCaption(this.getManager().getCaption());
      if (this.getEntity() != null)
        ecg.setEntityUuid(this.getEntity().getUuid());
      if (this.getEntityConstClass() != null)
        ecg.setEntityCaption(this.fetchEntityCaption());
      ecg.setNewState(this.state);
      ecg.setFieldName(fieldName);
      ecg.setFieldCaption(this.fetchFieldCaption(fieldName));
      ecg.setOldValue(objectToValue(oldValue));
      ecg.setNewValue(objectToValue(newValue));
      logMgr.save(ecg);

      return ecg;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  private String fetchFieldCaption(String fieldName) {
    Field[] fields = this.getEntityConstClass().getDeclaredFields();
    for (int i = 0; i < fields.length; i++)
      try {
        if (new String("CAPTION_" + fieldName.toUpperCase()).equals(fields[i].getName()))
          return (String) fields[i].get(null);
      } catch (IllegalArgumentException e) {
      } catch (IllegalAccessException e) {
      }
    return this.getEntityConstClass().getSimpleName();
  }

  private String objectToValue(Object o) throws BusinessException {
    if (o == null)
      return null;
    else if (o instanceof String)
      return (String) o;
    else if (o instanceof Integer)
      return ((Integer) o).toString();
    else if (o instanceof Date)
      return FormatSettings.formatDatetime(FormatSettings.SDFyMdHms, (Date) o);
    else if (o instanceof BigDecimal)
      return ((BigDecimal) o).toString();
    else if (o instanceof Boolean)
      return ((Boolean) o).toString();
    else
      throw new BusinessException("对象类型不支持:" + o.toString());
  }
}
